/**
 * Copyright (c) 2016-2019 ykf All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package com.basic.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.basic.common.exception.RRException;
import com.basic.common.utils.*;
import com.basic.modules.sys.dao.SysRoleDao;
import com.basic.modules.sys.dao.SysUserDao;
import com.basic.modules.sys.entity.SysMenuEntity;
import com.basic.modules.sys.entity.SysRoleEntity;
import com.basic.modules.sys.entity.SysRoleMenuEntity;
import com.basic.modules.sys.service.*;
import com.basic.modules.ykf.entity.YkfCompanyDeptEntity;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 角色
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service("sysRoleService")
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRoleEntity> implements SysRoleService {
	@Autowired
	private SysRoleMenuService sysRoleMenuService;
	@Autowired
	private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleService sysUserRoleService;
	@Lazy
	@Autowired
	private SysMenuService sysMenuService;

	@Lazy
	@Autowired
	private SysUserService sysUserService;

	@Override
	public PageUtils queryPage(ParamsModel<SysRoleEntity> paramsModel) {
		QueryWrapper<SysRoleEntity> queryWrapper = ParamUtils.createQueryWrapper(paramsModel);
		if (ObjectUtil.isNotEmpty(paramsModel.getCondition().getKeyword())) {
			String keyword = paramsModel.getCondition().getKeyword();
			queryWrapper.lambda().and(wrapper -> wrapper.like(SysRoleEntity::getRoleName, keyword)
					.or().like(SysRoleEntity::getRemark, keyword));
		}

		//授权公司
		List<String> powerCompanyNos = sysUserService.getPowerCompanyNos();
		if (ObjectUtil.isNotEmpty(powerCompanyNos)) {
			if (!powerCompanyNos.contains("ALL")) {
				queryWrapper.lambda().in(SysRoleEntity::getCompanyPerms, powerCompanyNos);
			}
		} else {
			return new PageUtils();
		}
		IPage<SysRoleEntity> page = this.page(
				new Query<SysRoleEntity>().getPage(BeanUtil.beanToMap(paramsModel.getPage())),
				queryWrapper
		);

		if (ObjectUtil.isNotEmpty(page) && ObjectUtil.isNotEmpty(page.getRecords())) {
			for (SysRoleEntity record : page.getRecords()) {
				record.setPermMenuCount(0);
				//查询授权页面个数
				QueryWrapper<SysMenuEntity> menuQueryWrapper = new QueryWrapper<>();
				menuQueryWrapper.lambda().eq(SysMenuEntity::getType, 1);
				List<SysMenuEntity> menuList = sysMenuService.list(menuQueryWrapper);
				if (ObjectUtil.isNotEmpty(menuList)) {
					List<Long> menuIds = menuList.stream().map(SysMenuEntity::getMenuId).collect(Collectors.toList());
					QueryWrapper<SysRoleMenuEntity> roleMenuEntityQueryWrapper = new QueryWrapper<>();
					roleMenuEntityQueryWrapper.lambda().eq(SysRoleMenuEntity::getRoleId, record.getRoleId())
							.in(SysRoleMenuEntity::getMenuId, menuIds);
					int count = sysRoleMenuService.count(roleMenuEntityQueryWrapper);
					record.setPermMenuCount(count);
				}
			}
		}
		return new PageUtils(page);
	}

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRole(SysRoleEntity role) {
        role.setCreateTime(new Date());
        this.save(role);

        //检查权限是否越权
        checkPrems(role);
		List<Long> menuIdList = role.getMenuIdList();
		//查询父节点
		QueryWrapper<SysMenuEntity> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().in(SysMenuEntity::getMenuId, menuIdList);
		List<SysMenuEntity> list = sysMenuService.list(queryWrapper);
		if (ObjectUtil.isNotEmpty(list)) {
			List<Long> parentIds = list.stream().map(SysMenuEntity::getParentId).distinct().collect(Collectors.toList());
			for (Long item : parentIds) {
				if (!menuIdList.contains(item)) {
					menuIdList.add(item);
				}
			}
		}
		//保存角色与菜单关系
        sysRoleMenuService.saveOrUpdate(role.getRoleId(), menuIdList);
    }



	@Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysRoleEntity role) {
        this.updateById(role);
        //检查权限是否越权
        checkPrems(role);
		//查询父节点
		List<Long> menuIdList = role.getMenuIdList();
		QueryWrapper<SysMenuEntity> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().in(SysMenuEntity::getMenuId, menuIdList);
		List<SysMenuEntity> list = sysMenuService.list(queryWrapper);
		if (ObjectUtil.isNotEmpty(list)) {
			List<Long> parentIds = list.stream().map(SysMenuEntity::getParentId).distinct().collect(Collectors.toList());
			for (Long item : parentIds) {
				if (!menuIdList.contains(item)) {
					menuIdList.add(item);
				}
			}
		}
        //更新角色与菜单关系
        sysRoleMenuService.saveOrUpdate(role.getRoleId(), menuIdList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] roleIds) {
        //删除角色
        this.removeByIds(Arrays.asList(roleIds));

        //删除角色与菜单关联
        sysRoleMenuService.deleteBatch(roleIds);

        //删除角色与用户关联
        sysUserRoleService.deleteBatch(roleIds);
    }


    @Override
	public List<Long> queryRoleIdList(Long createUserId) {
		return baseMapper.queryRoleIdList(createUserId);
	}

	/**
	 * 检查权限是否越权
	 */
	private void checkPrems(SysRoleEntity role){
		//如果不是超级管理员，则需要判断角色的权限是否超过自己的权限
		if(role.getCreateUserId() == Constant.SUPER_ADMIN){
			return ;
		}

		//查询用户所拥有的菜单列表
		List<Long> menuIdList = sysUserDao.queryAllMenuId(role.getCreateUserId());

		//判断是否越权
		if(!menuIdList.containsAll(role.getMenuIdList())){
			throw new RRException("新增角色的权限，已超出你的权限范围");
		}
	}
}
